package com.tbit.uqbike.push.service.impl;

import com.tbit.uqbike.push.constant.*;
import com.tbit.uqbike.push.dao.core.AccountConfigExtDao;
import com.tbit.uqbike.push.dao.core.CallConfigDao;
import com.tbit.uqbike.push.pojo.*;
import com.tbit.uqbike.push.service.*;
import com.tbit.uqbike.push.util.DateTimeUtil;
import com.tbit.uqbike.push.util.GeoUtil;
import com.tbit.uqbike.push.util.LogUtil;
import com.tbit.uqbike.push.util.ThreadUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.text.DecimalFormat;
import java.util.*;

@Service("machineStatusService")
@Slf4j
public class MachineStatusServiceImpl implements MachineStatusService {
    /**
     * 经纬度格式化
     */
    private DecimalFormat df = new DecimalFormat("#.########");
    @Autowired
    private MachineService machineService;
    @Autowired
    private UserService userService;
    @Autowired
    private ThreadPoolTaskExecutor taskExecutor;
    @Autowired
    private TerControlService terControlService;
    @Autowired
    private RedisService redisService;
    @Autowired
    private GeoService geoService;
    @Autowired
    private CallConfigDao callConfigDao;
    @Autowired
    private AccountConfigExtDao accountConfigExtDao;


    @Override
    public synchronized void initMachineData() {
        if (SystemData.machineNOMachineIdMap.size() == 0 || SystemData.machineIdAccountIdMap.size() == 0) {
            /**同步时间*/
            SystemData.lastSynTime = DateTimeUtil.getNowTime();

            /**加载所有设备信息*/
            List<MachineBase> machineBases = machineService.getAllMachineBase();
            for (MachineBase machineBase : machineBases) {
                SystemData.machineNOMachineIdMap.put(machineBase.getMachineNO(), machineBase.getMachineId());
                SystemData.machineIdAccountIdMap.put(machineBase.getMachineId(), machineBase.getAccountId());
                SystemData.machineNOUserCodeMap.put(machineBase.getMachineNO(), machineBase.getUserCode());
                SystemData.machineNOMachineTypeMap.put(machineBase.getMachineNO(), machineBase.getMachineType());
            }
            LogUtil.info("设备初始化" + SystemData.machineNOMachineIdMap.size() + "]");
        }
        if (SystemData.accountIdGeoListMap.size() == 0) {
            SystemData.lastSynGeoTime = DateTimeUtil.getNowTime();
            List<Geo> geos = geoService.getAll();
            if (geos.size() > 0) {
                for (Geo geo : geos) {
                    if (!SystemData.accountIdGeoListMap.containsKey(geo.getAccountId())) {
                        SystemData.accountIdGeoListMap.put(geo.getAccountId(), new ArrayList<Geo>());
                    }
                    SystemData.accountIdGeoListMap.get(geo.getAccountId()).add(geo);
                }
                LogUtil.info("同步电子围栏数量[" + geos.size() + "]");
            }
        }

    }

    @Override
    public void updatePosition(TerPosition terPosition) {

        /**加载设备数据*/
        initMachineData();

        /**查询设备id*/
        Integer machineId = SystemData.machineNOMachineIdMap.get(terPosition.getMachineNO());
        if (machineId == null) {
            return;
        }
        boolean isCheckForbidden = true;

        /**过滤非GPS定位*/
        if (terPosition.getPointType() == 1 || terPosition.getPointType() == 6) {
            /**电子围栏判断*/
            Integer accountId = SystemData.machineIdAccountIdMap.get(machineId);
            if (accountId != null && SystemData.accountIdGeoListMap.containsKey(accountId)) {
                List<Geo> geos = SystemData.accountIdGeoListMap.get(accountId);
                Point pointNew = new Point(terPosition.getLon(), terPosition.getLat());
                for (Geo geo : geos) {

                    List<Point> geoPoints = GeoUtil.getPoints(geo.getPoints());

                    /**判断点是否出围栏超速*/
                    if (!GeoUtil.IsPtInPoly(pointNew, geoPoints)) {
                        /**判断出超速*/
                        if (SystemData.machineAlarm.get(accountId) != null && SystemData.machineAlarm.get(accountId) != 0
                                && terPosition.getSpeed() >= SystemData.machineAlarm.get(accountId)) {

                            String machineIdRedis = RedisConstant.REDIS_MACHINE_GEOOUTSPEED_ID + machineId;
                            String machineIdRedisValue = redisService.get(machineIdRedis);
                            if (machineIdRedisValue == null) {
                                LogUtil.info("超速告警缓存第一次：" + terPosition.getMachineNO());
                                redisService.add(machineIdRedis, System.currentTimeMillis() + "", 60);
                            } else {

                                Long changeTime = Long.valueOf(machineIdRedisValue);
                                if (changeTime > 2) {
                                    Long second = (System.currentTimeMillis() - changeTime) / 1000;
                                    LogUtil.info("超速告警缓存第二次：" + terPosition.getMachineNO());
                                    redisService.add(machineIdRedis, String.valueOf(2), second.intValue());
                                } else {
                                    /**添加告警缓存*/
                                    LogUtil.info("超速告警缓存第三次：" + terPosition.getMachineNO());

                                    String accountIdKey = RedisConstant.REDIS_MACHINE_GEOOUTSPEED_ID_MAP_LIST + accountId;
                                    List<String> machineIdList = redisService.getList(accountIdKey);
                                    if (machineIdList == null || machineIdList.isEmpty() || !machineIdList.contains(String.valueOf(machineId))) {
                                        redisService.andToList(accountIdKey, String.valueOf(machineId));
                                    }
                                    redisService.delet(machineIdRedis);
                                }
                            }
                        }
                    }
                }
            }
        }

        /** 只判断骑行车辆 */
        if (SystemData.machineBorrowMap.containsKey(machineId)) {
            /**过滤非GPS定位*/
            if (terPosition.getPointType() == 1 || terPosition.getPointType() == 6) {
                /**电子围栏判断*/
                Integer accountId = SystemData.machineIdAccountIdMap.get(machineId);
                if (accountId != null && SystemData.accountIdGeoListMap.containsKey(accountId)) {
                    List<Geo> geos = SystemData.accountIdGeoListMap.get(accountId);
                    Point pointNew = new Point(terPosition.getLon(), terPosition.getLat());
                    for (Geo geo : geos) {

                        List<Point> geoPoints = GeoUtil.getPoints(geo.getPoints());


                        /**判断老的位置是否在电子围栏内*/
                        Point pointOld = SystemData.machineStatusOldMap.get(machineId);
                        if (pointOld != null) {
                            /**位置在区域内，并在不断靠近围栏，触发即将出围栏预警*/
                            if (GeoUtil.IsPtInPoly(pointOld, geoPoints) && GeoUtil.IsPtInPoly(pointNew, geoPoints)
                                    && GeoUtil.getDistance(pointNew, geoPoints) <= 100) {
                                // LogUtil.info("设备[" + terPosition.getMachineNO() + "]" + " " +"位置[" + df.format(terPosition.getLat()) + "," + df.format(terPosition.getLon()) + "]");
                                //LogUtil.info(terPosition.getMachineNO()+"即将使出围栏");
                                String tmp = redisService.get(RedisConstant.REDIS_MACHINE_NEAR_GEO_WARN + terPosition.getMachineNO());
                                User user = userService.getByMachineId(machineId);
                                if (user != null && (tmp == null || Integer.valueOf(tmp) < 3)) {
                                    //异步处理
                                    ThreadServiceImpl threadService = new ThreadServiceImpl();
                                    threadService.setRedisService(redisService);
                                    threadService.setUser(user);
                                    threadService.setMachineNO(terPosition.getMachineNO());
                                    threadService.setGeo(geo);
                                    threadService.setTerControlService(terControlService);
                                    taskExecutor.execute(new ThreadUtils(threadService, ThreadType.GEO_WARN));
                                }
                            }
                            /**旧的点距离围栏距离小于100米，新的点大于100米，认为设备已跑出预警区域，去除预警标志*/
                            if (GeoUtil.IsPtInPoly(pointOld, geoPoints) && GeoUtil.IsPtInPoly(pointNew, geoPoints) && GeoUtil.getDistance(pointOld, geoPoints) < 100 && GeoUtil.getDistance(pointNew, geoPoints) > 100) {
                                redisService.delet(RedisConstant.REDIS_MACHINE_NEAR_GEO_WARN + terPosition.getMachineNO());
                            }
                            String out = redisService.get("geoOut" + terPosition.getMachineNO());

                            /**第一次骑出围栏*/
                            if (!GeoUtil.IsPtInPoly(pointNew, geoPoints) && out == null) {
                                String newTime = DateTimeUtil.dateTimeToString(new Date(Long.parseLong(terPosition.getDt())));
                                LogUtil.info("设备[" + terPosition.getMachineNO() + "]，位置[" + df.format(terPosition.getLat()) + "," + df.format(terPosition.getLon()) + "]，时间[" + newTime + "]");
                                //防止设备漂移三次经纬度判断
                                LogUtil.warn("[" + terPosition.getMachineNO() + "]设备已经行驶出电子围栏[初次判断]");
                                /** 电子围栏三次校验 */
                                redisService.add("geoOut" + terPosition.getMachineNO(), "1",24*3600);
                                //断电
                                redisService.add("cutPower" + terPosition.getMachineNO(), "1",30*60);
                                //短信 语音发送
                                redisService.add("msgVoice" + terPosition.getMachineNO(), "1",24*3600);
                                //记录初次出围栏时间，用于判断出围栏后多久断电
                                SystemData.geoCutTime.put(terPosition.getMachineNO(), DateTimeUtil.getNowTime());
                                //单车出围栏立即出发定位
                                Integer machineType = SystemData.machineNOMachineTypeMap.get(terPosition.getMachineNO());
                                if(MachineConstant.MACHINE_TYPE_BIKE.equals(machineType)){
                                    terControlService.sendControl(UUID.randomUUID().toString(), terPosition.getMachineNO(), ControlTypeConstant.CONTROL_TYPE_CONTROL, ControlTypeConstant.CONTROL_TYPE_LOCATION, "", "自行车靠近围栏触发立即定位");
                                }
                            }

                            /**第二次后出围栏*/
                            if (!GeoUtil.IsPtInPoly(pointNew, geoPoints)) {
                                isCheckForbidden = false;
                                //if (!GeoUtil.IsPtInPoly(pointOld, geoPoints) && !GeoUtil.IsPtInPoly(pointNew, geoPoints)) {
                                LogUtil.info("设备[" + terPosition.getMachineNO() + "]，位置[" + df.format(terPosition.getLat()) + "," + df.format(terPosition.getLon()) + "]，时间[" + DateTimeUtil.dateTimeToString(new Date(Long.parseLong(terPosition.getDt()))) + "]");
                                String s = redisService.get("geoOut" + terPosition.getMachineNO());
                                if (s != null) {
                                    Integer size = Integer.valueOf(s) + 1;
                                    redisService.add("geoOut" + terPosition.getMachineNO(), String.valueOf(size),24*3600);
                                    String tmp = redisService.get(RedisConstant.REDIS_MACHINE_NEAR_GEO_WARN + terPosition.getMachineNO());
                                    /**连续2个点超出围栏,或者有触发即将出围栏预警，有轨迹点出围栏*/
                                    if ((size >= 1 && tmp != null) || size >= 3) {
                                        /**获取设备是否有发送断电指令*/
                                        String string = redisService.get(RedisConstant.REDIS_MACHINE_OUTGEO_PUSH + terPosition.getMachineNO());
                                        String lock = redisService.get(RedisConstant.REDIS_MACHINE_OUT_GEO_LOCK + terPosition.getMachineNO());
                                        if (lock == null) {
                                            lock = "1";
                                        }
                                        Integer distance=500;
                                        Integer machineType = SystemData.machineNOMachineTypeMap.get(terPosition.getMachineNO());
                                        // if(size>10&&size<20&&GeoUtil.getDistance(pointNew, geoPoints)>GeoUtil.getDistance(pointOld, geoPoints)&&(string!=null&&Integer.valueOf(string)>=3)){
                                        try {
                                            //获取超区锁车距离配置
                                             distance = Optional.ofNullable(accountConfigExtDao.selectByAccountIdAndKey(geo.getAccountId(), AccountConfigConstant.OUT_BIKE_LOCK_DISTANCE))
                                                    .map(AccountConfigExt::getParamValue)
                                                    .map(Integer::parseInt)
                                                    .filter(x -> x > 0)
                                                    .orElse(500);
                                            String time = redisService.get(String.format("BackCyclingTimeStart#%s", terPosition.getMachineNO()));
                                            //自行车临时开锁逻辑兼容
                                            if(MachineConstant.MACHINE_TYPE_BIKE.equals(machineType)&&GeoUtil.getDistance(pointNew, geoPoints) >= distance
                                                    &&StringUtils.hasText(time) ){
                                                Integer backCycling = Optional.ofNullable(accountConfigExtDao.selectByAccountIdAndKey(geo.getAccountId(), AccountConfigConstant.TEMPORARYPOWERTIME))
                                                        .map(AccountConfigExt::getParamValue)
                                                        .map(Integer::parseInt)
                                                        .filter(x -> x > 0)
                                                        .orElse(5);
                                                String power = redisService.get(RedisConstant.REDIS_MACHINE_POWER + terPosition.getMachineNO());
                                                // 配置了断电往回骑  开始往回骑行的时间超过配置的时间就下发锁车指令
                                                if ((backCycling * 60) <= DateTimeUtil.getSecondDiffer(time)&&power==null) {
                                                    String serialNo = UUID.randomUUID().toString();
                                                    terControlService.sendControl(serialNo, terPosition.getMachineNO(), ControlTypeConstant.CONTROL_TYPE_CONTROL, ControlTypeConstant.CONTROL_TYPE_LOCK, "1", "自行车出围栏锁车");
                                                    redisService.add(RedisConstant.REDIS_MACHINE_POWER+terPosition.getMachineNO(),"1",15*60);
                                                    return;
                                                }
                                            }
                                        }catch (Exception e){
                                            log.error(String.format("临时通电异常%s",terPosition.getMachineNO()));
                                        }
                                        //log.info(terPosition.getMachineNO()+",距离="+distance);
                                        /**判断是否往外骑,强行锁车*/
                                        //骑出围栏外500米 兼容设置断电开关
                                        if (GeoUtil.getDistance(pointNew, geoPoints) >= distance && Integer.valueOf(lock) <= 3 && GeoUtil.getDistance(pointNew, geoPoints) > GeoUtil.getDistance(pointOld, geoPoints) &&
                                                ((string != null && Integer.valueOf(string) >= 3) || MachineConstant.MACHINE_TYPE_BIKE.equals(machineType))) {
                                            String serialNo = UUID.randomUUID().toString();
                                            LogUtil.info("machineNO=" + terPosition.getMachineNO() + "，断电后继续骑行，强行锁车" + "serialNo=" + UUID.randomUUID().toString());
                                            /**单车锁车兼容普通锁车，不能下发强制锁车*/
                                            if (machineType != null && MachineConstant.MACHINE_TYPE_BIKE.equals(machineType)) {

                                                terControlService.sendControl(serialNo, terPosition.getMachineNO(), ControlTypeConstant.CONTROL_TYPE_CONTROL, ControlTypeConstant.CONTROL_TYPE_LOCK, "1", "自行车出围栏锁车");
                                            } else {
                                                terControlService.sendControl(serialNo, terPosition.getMachineNO(), ControlTypeConstant.CONTROL_TYPE_CONTROL, ControlTypeConstant.CONTROL_TYPE_LOCK_FOCUS, "", "断电后继续骑行，强行锁车");
                                            }
                                            isCheckForbidden = false;
                                            /**记录锁车标志*/
                                            redisService.add(RedisConstant.REDIS_MACHINE_OUT_GEO_LOCK + terPosition.getMachineNO(), String.valueOf(Integer.valueOf(lock) + 1), 15 * 60);
                                        }

                                        //防止设备漂移 三次经纬度判断
                                        //redisService.delet("geoIn" + terPosition.getMachineNO());
                                        LogUtil.warn("[" + terPosition.getMachineNO() + "]设备已经行驶出电子围栏");
                                        redisService.add(RedisConstant.REDIS_MACHINE_OUTGEO_STATUS + terPosition.getMachineNO(), "1");
                                        //log.info(terPosition.getMachineNO()+",geo="+geo+",machineType="+machineType);
                                        /**围栏开关打开，并且是电单车才能触发断电*/
                                        if (geo.getGeoSwitch() != null && geo.getGeoSwitch() == GeoSwitchType.SWITCH_OPEAN && MachineConstant.MACHINE_TYPE_ELECT_BIKE.equals(machineType)) {
                                            User user = userService.getByMachineId(machineId);

                                            if (user != null && (string == null || Integer.valueOf(string) < 3) && GeoUtil.getDistance(pointNew, geoPoints) > GeoUtil.getDistance(pointOld, geoPoints)) {
                                                //异步处理
                                                ThreadServiceImpl threadService = new ThreadServiceImpl();
                                                threadService.setGeo(geo);
                                                threadService.setUser(user);
                                                threadService.setTerPosition(terPosition);
                                                threadService.setMachineNO(terPosition.getMachineNO());
                                                threadService.setRedisService(redisService);
                                                threadService.setTerControlService(terControlService);
                                                threadService.setCallConfigDao(callConfigDao);
                                                threadService.setAccountConfigExtDao(accountConfigExtDao);
                                                taskExecutor.execute(new ThreadUtils(threadService, ThreadType.GEO_OUTSIDE));
                                            } else {
                                                LogUtil.warn("[" + terPosition.getMachineNO() + "]设备已发送断电，重复不再发送");
                                            }
                                        }
                                    }
                                }
                            }

                            /**重新驶入围栏*/
                            if (!GeoUtil.IsPtInPoly(pointOld, geoPoints) && GeoUtil.IsPtInPoly(pointNew, geoPoints)) {
                                LogUtil.info("设备[" + terPosition.getMachineNO() + "]，位置[" + df.format(terPosition.getLat()) + "," + df.format(terPosition.getLon()) + "]，时间[" + DateTimeUtil.dateTimeToString(new Date(Long.parseLong(terPosition.getDt()))) + "]");

                                /**终端有出围栏的记录，才会触发进入围栏上电*/
                                String s = redisService.get("geoOut" + terPosition.getMachineNO());
                                if (s != null) {
                                    Integer size = Integer.valueOf(s);
                                    if (size > 1) {
                                        LogUtil.info("[" + terPosition.getMachineNO() + "]设备重新驶入电子围栏");
                                        /** 清除设备驶出电子围栏记录*/
                                        redisService.delet("geoOut" + terPosition.getMachineNO());
                                        /** 清除设备发送断电指令记录*/
                                        redisService.delet(RedisConstant.REDIS_MACHINE_OUTGEO_PUSH + terPosition.getMachineNO());
                                        /** 清除设备发送超区语音指令记录*/
                                        redisService.delet(RedisConstant.REDIS_MACHINE_OUT_GEO_VOICE + terPosition.getMachineNO());
                                        /** 清除设备发送强行锁车指令记录*/
                                        redisService.delet(RedisConstant.REDIS_MACHINE_OUT_GEO_LOCK + terPosition.getMachineNO());
                                        /** 清除设备断电指令缓存 */
                                        redisService.delet("cutPower" + terPosition.getMachineNO());
                                        redisService.delet(RedisConstant.REDIS_MACHINE_POWER+terPosition.getMachineNO());
                                        /** 清除设备快出围栏预警*/
                                        //redisService.delet(RedisConstant.REDIS_MACHINE_NEAR_GEO_WARN+ terPosition.getMachineNO());
                                        /** 设备驶入电子围栏*/
                                        if (geo.getGeoSwitch() != null && geo.getCutSwitch() == GeoSwitchType.SWITCH_OPEAN && geo.getRecoverSwitch() == GeoSwitchType.SWITCH_OPEAN) {
                                            User user = userService.getByMachineId(machineId);
                                            if (user != null) {
                                                //异步处理
                                                ThreadServiceImpl threadService = new ThreadServiceImpl();
                                                threadService.setRedisService(redisService);
                                                threadService.setUser(user);
                                                threadService.setMachineNO(terPosition.getMachineNO());
                                                threadService.setGeo(geo);
                                                threadService.setTerControlService(terControlService);
                                                taskExecutor.execute(new ThreadUtils(threadService, ThreadType.GEO_INSIDE));
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                /**禁行区逻辑*/
                if (isCheckForbidden) {
                    forbiddenCheck(machineId, terPosition);
                }
                /**判断后再更新电子围栏数据*/
                SystemData.machineStatusOldMap.put(machineId, new Point(terPosition.getLon(), terPosition.getLat()));
            }
        }

    }


    /**
     * 禁行区逻辑判断
     *
     * @param machineId
     * @param terPosition
     */
    public void forbiddenCheck(Integer machineId, TerPosition terPosition) {
        Point pointNew = new Point(terPosition.getLon(), terPosition.getLat());
        Integer accountId = SystemData.machineIdAccountIdMap.get(machineId);
        List<Forbidden> forbiddens = accountId == null ? new ArrayList<>() : SystemData.FleetIdToForbiddenMap.get(accountId);
        if (accountId != null && forbiddens != null && !forbiddens.isEmpty()) {
            for (Forbidden forbidden : forbiddens) {
                Point pointOld = SystemData.machineStatusOldMap.get(machineId);
                if (pointOld != null) {
                    List<Point> geoPoints = GeoUtil.getPoints(forbidden.getPoints());
                    /**靠近禁行区告警*/
                    if (!GeoUtil.IsPtInPoly(pointOld, geoPoints) && !GeoUtil.IsPtInPoly(pointNew, geoPoints)
                            && GeoUtil.getDistance(pointNew, geoPoints) <= forbidden.getDistance()) {
                        ForBiddenServiceImpl forBiddenService = new ForBiddenServiceImpl();
                        forBiddenService.setRedisService(redisService);
                        forBiddenService.setMachineNO(terPosition.getMachineNO());
                        forBiddenService.setTerControlService(terControlService);
                        taskExecutor.execute(new ThreadUtils(forBiddenService, ThreadType.GEO_NEAR_FORBIDDEN));
                        break;
                    }
                    /**旧的点距离围栏距离小于设定值，新的点大于设定值，认为设备已跑出预警区域，去除预警标志*/
                    if (!GeoUtil.IsPtInPoly(pointOld, geoPoints) && !GeoUtil.IsPtInPoly(pointNew, geoPoints)
                            && GeoUtil.getDistance(pointOld, geoPoints) < forbidden.getDistance()
                            && GeoUtil.getDistance(pointNew, geoPoints) > forbidden.getDistance()) {
                        redisService.delet(RedisConstant.REDIS_MACHINE_NEAR_FORBIDDEN_WARN + terPosition.getMachineNO());
                    }
                    /**两个点都进入禁行区触发断电*/
                    if (GeoUtil.IsPtInPoly(pointOld, geoPoints) && GeoUtil.IsPtInPoly(pointNew, geoPoints)) {
                        ForBiddenServiceImpl forBiddenService = new ForBiddenServiceImpl();
                        forBiddenService.setRedisService(redisService);
                        forBiddenService.setMachineNO(terPosition.getMachineNO());
                        forBiddenService.setTerControlService(terControlService);
                        taskExecutor.execute(new ThreadUtils(forBiddenService, ThreadType.GEO_OUT_FORBIDDEN));
                        redisService.add(RedisConstant.REDIS_MACHINE_FORBIDDEN_ID + terPosition.getMachineNO(), String.valueOf(forbidden.getForbiddenId()), 24 * 3600);
                        String outPower = redisService.get(RedisConstant.REDIS_BIKE_OUTFORBIDDEN_PUSH + terPosition.getMachineNO());
                        if (outPower == null) {
                            outPower = "0";
                        }
                        //自行车超区触发超区锁车指令
                        Integer machineType = SystemData.machineNOMachineTypeMap.get(terPosition.getMachineNO());
                        if (MachineConstant.MACHINE_TYPE_BIKE.equals(machineType)&&Integer.valueOf(outPower)<3) {
                            String serialNo = UUID.randomUUID().toString();
                            terControlService.sendControl(serialNo, terPosition.getMachineNO(), ControlTypeConstant.CONTROL_TYPE_CONTROL, ControlTypeConstant.CONTROL_TYPE_LOCK, "1", "自行车进入禁行区锁车");
                            redisService.add(RedisConstant.REDIS_BIKE_OUTFORBIDDEN_PUSH + terPosition.getMachineNO(),String.valueOf(Integer.valueOf(outPower)+1),30*60);
                        }
                        break;
                    }
                    /**重新出禁行区触发上电*/
                    if (!GeoUtil.IsPtInPoly(pointOld, geoPoints) && !GeoUtil.IsPtInPoly(pointNew, geoPoints)) {
                        String outForId = redisService.get(RedisConstant.REDIS_MACHINE_FORBIDDEN_ID + terPosition.getMachineNO());
                        if (outForId != null && (outForId.equals(String.valueOf(forbidden.getForbiddenId())) || outForId.equals(terPosition.getMachineNO()))) {
                            ForBiddenServiceImpl forBiddenService = new ForBiddenServiceImpl();
                            forBiddenService.setRedisService(redisService);
                            forBiddenService.setMachineNO(terPosition.getMachineNO());
                            forBiddenService.setTerControlService(terControlService);
                            taskExecutor.execute(new ThreadUtils(forBiddenService, ThreadType.GEO_INSIDE_FORBIDDEN));
                            redisService.delet(RedisConstant.REDIS_MACHINE_FORBIDDEN_ID + terPosition.getMachineNO());
                            redisService.delet(RedisConstant.REDIS_BIKE_OUTFORBIDDEN_PUSH + terPosition.getMachineNO());
                            redisService.delet(RedisConstant.REDIS_MACHINE_OUTFORBIDDEN_PUSH + terPosition.getMachineNO());
                        }
                        continue;
                    }
                }
            }

        }
    }

}  